<script setup>

import dialogJson from "@/components/dialog/dialogJson.js";
import {inject, nextTick, onMounted, ref} from "vue";
import {fabric} from 'fabric';
import {baseStore} from "@/store/baseStore.js";
import {CloseBold, Delete} from "@element-plus/icons-vue";
import ImageClassificationService from "@/service/impl/ImageClassificationService.js"
import VideoService from "@/service/impl/VideoService.js";
import FileUploadService from "@/service/impl/FileUploadService.js";


let bs = baseStore()
let {menuFoldState} = storeToRefs(bs)
const props = defineProps({
    editImageItem: {
        type: Object,
        default: () => {
            return dialogJson()
        }
    }
})
// 当前显示的图片索引
let canvas = null, offsetX = 0, offsetY = 0, scaleFactor = 1,tempCanvas = null,video = null,animationFrameId = null,currentIndex = 0;
const imageItems = ref([])
const featuresList = ref([])
const emits = defineEmits(['onSave','onClose'])
const message = inject('message')
const url = window.webConfig.apiUrl()
// 添加视频边界变量
let videoBounds = {left: 0, top: 0, right: 0, bottom: 0};
const videoProgress = ref({
    progress: 0,
    progressMax: 100,
    start: false
})
const videoImages = ref([])
let frameMap = {}


const show = () => {
    let elementById = document.getElementById("canvas-row");
    canvas = new fabric.Canvas('canvas', {
        // 保持对象的堆叠顺序，防止对象在添加时重新排序
        preserveObjectStacking: true,
        // 启用高分辨率缩放，确保在高 DPI 屏幕上显示清晰。
        enableRetinaScaling: true,
        renderOnAddRemove: false, // 关闭自动渲染
        skipOffscreen: true       // 跳过屏幕外渲染
    });
    canvas.setWidth(elementById.clientWidth);
    canvas.setHeight(elementById.clientHeight);
    // 设置背景
    drawBg(url + props.editImageItem.data.url)
    // 查询特征
    ImageClassificationService.featuresList({
        languageClassificationId: props.editImageItem.data.languageClassificationId
    }).then(res => featuresList.value = res.data)
    // 查询图片
    VideoService.videoByImages({
        url: props.editImageItem.data.url
    }).then(res => {
        videoImages.value = res.data
        imageItems.value = videoImages.value.find(item => item?.videoFrames === 0)?.featuresConfig || []
        nextTick(() => {
            rectangle()
            initRect()
        })
    })
}

const restWindow = () => {
    // 监听窗口缩放事件
    window.addEventListener('resize', function () {
        if (!props.editImageItem.show) {
            return
        }
        let elementById = document.getElementById("canvas-row");
        canvas.setWidth(elementById.clientWidth);
        canvas.setHeight(elementById.clientHeight);
        updateFrame()
        // 重新计算框选矩形的位置和尺寸
        canvas.getObjects().filter(obj => obj instanceof fabric.Rect || obj instanceof fabric.Text)
            .forEach(obj => {
                let find = imageItems.value.find(item => item.id === obj.id);
                if (obj instanceof fabric.Rect) {
                    obj.set({
                        left: find.x * scaleFactor + offsetX,
                        top: find.y * scaleFactor + offsetY,
                        width: find.width * scaleFactor,
                        height: find.height * scaleFactor
                    });
                }
                if (obj instanceof fabric.Text) {
                    obj.set({
                        left: find.x * scaleFactor + offsetX,
                        top: find.y * scaleFactor + offsetY - 20,
                    });
                }
            })
        canvas.renderAll();
    });
}

function updateFrame() {
    const canvasWidth = canvas.getWidth();
    const canvasHeight = canvas.getHeight();
    const videoWidth = video.videoWidth;
    const videoHeight = video.videoHeight;
    if (videoWidth / canvasWidth > videoHeight / canvasHeight) {
        scaleFactor = canvasWidth / videoWidth;
    } else {
        scaleFactor = canvasHeight / videoHeight;
    }
    // 计算缩放后的图片宽度和高度
    const scaledVideoWidth = videoWidth * scaleFactor;
    const scaledVideoHeight = videoHeight * scaleFactor;
    // 计算水平和垂直方向的偏移量，以实现居中
    offsetX = (canvasWidth - scaledVideoWidth) / 2;
    offsetY = (canvasHeight - scaledVideoHeight) / 2;
    // 记录视频边界
    videoBounds = {
        left: offsetX,
        top: offsetY,
        right: offsetX + scaledVideoWidth,
        bottom: offsetY + scaledVideoHeight
    };
    tempCanvas = document.createElement('canvas');
    const tempCtx = tempCanvas.getContext('2d');
    tempCanvas.width = canvasWidth;
    tempCanvas.height = canvasHeight;
    if(animationFrameId){
        cancelAnimationFrame(animationFrameId);
        animationFrameId = null
    }
    // 清空画布
    tempCtx.clearRect(0, 0, tempCanvas.width, tempCanvas.height);
    // 绘制缩放后的视频帧
    tempCtx.drawImage(
        video,
        0, 0, videoWidth, videoHeight,      // 源尺寸
        offsetX, offsetY, scaledVideoWidth, scaledVideoHeight               // 目标尺寸
    );
    fabric.Image.fromURL(tempCanvas.toDataURL(), img => {
        canvas.setBackgroundImage(img, () => {
            canvas.renderAll();
        }, {
            originX: 'left',
            originY: 'top',
            crossOrigin: 'anonymous'
        });
    },{crossOrigin: 'anonymous'});
    animationFrameId = requestAnimationFrame(updateFrame);
}

const initRect = () => {
    imageItems.value.forEach(item => {
        let x = Math.floor(item.x * scaleFactor + offsetX)
        let y = Math.floor(item.y * scaleFactor + offsetY)
        const rect = new fabric.Rect({
            id: item.id,
            left: x,
            top: y,
            width: item.width * scaleFactor,
            height: item.height * scaleFactor,
            stroke: 'red',
            fill: 'transparent',
            strokeWidth: 1,
            selectable: true,
        });
        // 创建文本对象
        const text = new fabric.Text(`${item.featuresName}`, {
            id: item.id,
            left: x,
            top: y - 20, // 将文本放置在矩形上方
            fill: 'red',
            fontSize: 15,
            selectable: false
        });
        canvas.add(text);
        canvas.add(rect);
        rectEvent(rect, text)
    })
}

const rectEvent = (rect, text) => {
    // 监听框的缩放事件
    rect.on('scaling', function () {
        const newWidth = rect.getScaledWidth();
        const newHeight = rect.getScaledHeight();
        // console.log('框正在缩放，新的宽度:', newWidth, '新的高度:', newHeight);
    });
    // 监听框的修改完成事件
    rect.on('modified', function () {
        const newWidth = rect.getScaledWidth();
        const newHeight = rect.getScaledHeight();
        // console.log('框修改完成，新的宽度:', newWidth, '新的高度:', newHeight);
        // 更新 imageItems 中的信息
        const relativeLeft = (rect.left - offsetX) / scaleFactor;
        const relativeTop = (rect.top - offsetY) / scaleFactor;
        const relativeWidth = newWidth / scaleFactor;
        const relativeHeight = newHeight / scaleFactor;
        let item = imageItems.value.find(item => item.id === rect.id);
        if (item) {
            item.x = Math.floor(relativeLeft)
            item.y = Math.floor(relativeTop)
            item.width = Math.floor(relativeWidth)
            item.height = Math.floor(relativeHeight)
        }
    });
    // 监听框的移动事件
    rect.on('moving', function () {

        // 限制矩形在视频范围内
        const rectWidth = rect.getScaledWidth();
        const rectHeight = rect.getScaledHeight();
        // 限制左边界
        if (rect.left < videoBounds.left) {
            rect.set({ left: videoBounds.left });
        }
        // 限制右边界
        if (rect.left + rectWidth > videoBounds.right) {
            rect.set({ left: videoBounds.right - rectWidth });
        }
        // 限制上边界
        if (rect.top < videoBounds.top) {
            rect.set({ top: videoBounds.top });
        }
        // 限制下边界
        if (rect.top + rectHeight > videoBounds.bottom) {
            rect.set({ top: videoBounds.bottom - rectHeight });
        }

        let x = Math.floor(rect.left)
        let y = Math.floor(rect.top - 20)
        // let texts = text.text.split(":")
        // text.text = `${texts.length > 1? texts[0]+":" : ''}(${x},${y})`
        text.set({
            left: x,
            top: y
        });
        canvas.renderAll();
    });
}


const rectangle = () => {
    let isDrawing = false, text = null, rect = null, startPoint = null, moveX = 0, moveY = 0, id = null;
    // 有数据则
    // 监听鼠标按下事件
    canvas.on('mouse:down', function (options) {
        // 检查是否有选中的对象，如果有则不创建新框
        if (canvas.getActiveObject()) {
            return;
        }
        startPoint = options.pointer;
        // 如果点击在视频外部，不创建矩形
        if (startPoint.x < videoBounds.left || startPoint.x > videoBounds.right ||
            startPoint.y < videoBounds.top || startPoint.y > videoBounds.bottom) {
            return;
        }
        videoProgress.value.start = false
        video.pause();
        id = generateShortUuid()
        isDrawing = true;
        // 禁用对象选择
        canvas.selection = false;
        rect = new fabric.Rect({
            id: id,
            left: startPoint.x,
            top: startPoint.y,
            width: 0,
            height: 0,
            stroke: 'red',
            fill: 'transparent',
            strokeWidth: 1,
            selectable: true
        });
        // 创建文本对象
        let x = Math.floor(startPoint.x)
        let y = Math.floor(startPoint.y - 20)
        text = new fabric.Text(`参数`, {
            id: id,
            left: x,
            top: y, // 将文本放置在矩形上方
            fill: 'red',
            fontSize: 15,
            selectable: false
        });
        canvas.add(rect, text);
        // rect 缩放事件，移动事件
        rectEvent(rect, text)
    });
    // 监听鼠标移动事件
    canvas.on('mouse:move', function (options) {
        if (isDrawing) {
            const currentPoint = options.pointer;

            // 限制当前点在视频范围内
            const constrainedX = Math.min(Math.max(currentPoint.x, videoBounds.left), videoBounds.right);
            const constrainedY = Math.min(Math.max(currentPoint.y, videoBounds.top), videoBounds.bottom);


            moveX = constrainedX - startPoint.x;
            moveY = constrainedY - startPoint.y;
            rect.set({
                width: moveX,
                height: moveY
            });
            if (text) {
                // 更新文本位置
                let x = Math.floor(rect.left)
                let y = Math.floor(rect.top - 20)
                // let texts = text.text.split(":")
                // text.text = `${texts.length > 1? texts[0]+":" : ''}(${x},${y})`
                text.set({
                    left: x,
                    top: y
                });
            }
            canvas.renderAll();
        }
    });
    // 监听鼠标松开事件
    canvas.on('mouse:up', function () {
        // 防止误按
        if (isDrawing && (Math.abs(moveX) < 3 || Math.abs(moveY) < 3)) {
            canvas.remove(rect, text);
            rect = null
        }
        isDrawing = false;
        if (rect) {
            // 计算框相对于图片的坐标
            const relativeLeft = (rect.left - offsetX) / scaleFactor;
            const relativeTop = (rect.top - offsetY) / scaleFactor;
            // 计算框相对于图片的宽度和高度
            const relativeWidth = rect.width / scaleFactor;
            const relativeHeight = rect.height / scaleFactor;
            let item = imageItems.value.find(item => item.id === rect.id)
            if (item) {
                return
            }
            // 选中当前框
            canvas.setActiveObject(rect);
            canvas.selection = true;
            canvas.renderAll();
            imageItems.value.push({
                id: rect.id,
                typeID: null,
                featuresName: null,
                x: Math.floor(relativeLeft),
                y: Math.floor(relativeTop),
                width: Math.floor(relativeWidth),
                height: Math.floor(relativeHeight)
            });
            moveX = 0
            moveY = 0
            // console.log('框相对于图片的坐标 (x, y):', relativeLeft, relativeTop);
            // console.log('框相对于图片的宽度:', relativeWidth);
            // console.log('框相对于图片的高度:', relativeHeight);
        }
    });
}

const drawBg = (urls) => {
    video = document.getElementById('video');
    if (!video) return;
    video.crossOrigin = "anonymous";
    video.src = urls;
    // 修复2：改用canplaythrough事件
    video.addEventListener('canplaythrough', function onCanPlay() {
        video.removeEventListener('canplaythrough', onCanPlay);
        tempCanvas = document.createElement('canvas');
        const tempCtx = tempCanvas.getContext('2d');
        // 获取画布的宽度和高度
        const canvasWidth = canvas.getWidth();
        const canvasHeight = canvas.getHeight();
        tempCanvas.width = canvasWidth;
        tempCanvas.height = canvasHeight;
        // 修复4：创建持续渲染循环
        // 获取图片的原始宽度和高度
        const videoWidth = video.videoWidth;
        const videoHeight = video.videoHeight;
        // 计算适配比例
        const canvasAspect = canvasWidth / canvasHeight;
        const videoAspect = videoWidth / videoHeight;
        if (videoAspect > canvasAspect) {
            // 视频更宽，按宽度适配
            scaleFactor = canvasWidth / videoWidth;
        } else {
            scaleFactor = canvasHeight / videoHeight;
        }
        // 计算缩放后的图片宽度和高度
        const scaledVideoWidth = videoWidth * scaleFactor;
        const scaledVideoHeight = videoHeight * scaleFactor;
        // 计算水平和垂直方向的偏移量，以实现居中
        offsetX = (canvasWidth - scaledVideoWidth) / 2;
        offsetY = (canvasHeight - scaledVideoHeight) / 2;

        // 记录视频边界
        videoBounds = {
            left: offsetX,
            top: offsetY,
            right: offsetX + scaledVideoWidth,
            bottom: offsetY + scaledVideoHeight
        };

        function updateFrame() {
            // 清空画布
            tempCtx.clearRect(0, 0, tempCanvas.width, tempCanvas.height);
            // 绘制缩放后的视频帧
            tempCtx.drawImage(
                video,
                0, 0, videoWidth, videoHeight,      // 源尺寸
                offsetX, offsetY, scaledVideoWidth, scaledVideoHeight               // 目标尺寸
            );
            fabric.Image.fromURL(tempCanvas.toDataURL(), img => {
                canvas.setBackgroundImage(img, () => {
                    canvas.renderAll();
                }, {
                    originX: 'left',
                    originY: 'top',
                    crossOrigin: 'anonymous'
                });
            },{crossOrigin: 'anonymous'});
            if(animationFrameId){
                cancelAnimationFrame(animationFrameId);
            }
            animationFrameId = requestAnimationFrame(updateFrame);
        }
        video.addEventListener('play', () => {
            updateFrame();
        });
        video.addEventListener('ended', function () {
            cancelAnimationFrame(animationFrameId);
            videoProgress.value.start = false
            frameMap = {}
        });
        // 监听视频的 timeupdate 事件，更新进度条
        video.addEventListener('timeupdate', () => {
            const z = Math.floor(video.currentTime)
            videoProgress.value.progress = z;
            videoProgress.value.progressMax = video.duration;
            let map = frameMap[z]
            delete frameMap[z - 1]
            if(map){
                return;
            }
            frameMap[z] = true
            clearAllRect()
            let frame = videoImages.value.find(item => item?.videoFrames === z)
            if(!frame){
                clearAllRect()
                return
            }
            imageItems.value = frame?.featuresConfig || []
            initRect()
        });
        video.play();
        video.pause();
        restWindow(video)
    });
}

const clearAllRect = () => {
    imageItems.value = []
    const allObjects = canvas.getObjects();
    // 筛选出所有的矩形对象
    const element = allObjects.filter(obj => obj instanceof fabric.Rect || obj instanceof fabric.Text)
    if (element.length < 1) {
        return
    }
    element.forEach(item => canvas.remove(item))
}

const onDelRect = (val, idx) => {
    // 获取画布上的所有对象
    const allObjects = canvas.getObjects();
    // 筛选出所有的矩形对象
    const element = allObjects.filter(obj => ((obj instanceof fabric.Rect || obj instanceof fabric.Text) && obj.id === val.id))
    if (element.length < 1) {
        return
    }
    element.forEach(item => canvas.remove(item))
    imageItems.value.splice(idx, 1);
}

const generateShortUuid = () => {
    const timestamp = new Date().getTime().toString(36);
    const fullUuid = crypto.randomUUID();
    return fullUuid.replace(/-/g, '').slice(0, 8) + timestamp; // 取前 8 位
}

const onChangeFeaturesName = (fid, iid) => {
    let features = featuresList.value.find(item => item.id === fid)
    const element = canvas.getObjects().filter(obj => (obj instanceof fabric.Text) && obj.id === iid)
    let find = imageItems.value.find(item => item.id === iid);
    find.featuresName = features.featuresName
    element.forEach(item => item.text = `${features.featuresName}`)
    canvas.renderAll();
}

const onSave = async () =>  {
    for (let i = 0; i < imageItems.value.length; i++) {
        let image = imageItems.value[i]
        if (!image.typeID || !image.featuresName) {
            message.warning("请给标注添加特征值")
            return
        }
        if (image.x < 0 || image.y < 0) {
            message.warning("坐标不能小于0，移动框重新获取坐标")
            return
        }
    }

    let temp = document.createElement('canvas');
    temp.width = video.videoWidth * scaleFactor;
    temp.height = video.videoHeight  * scaleFactor;
    const tempCtx = temp.getContext('2d');
    tempCtx.drawImage(video, 0, 0, temp.width, temp.height);
    const base64 = temp.toDataURL('image/png')

    let z = Math.floor(video.currentTime);
    let item = videoImages.value.find(j => j?.videoFrames === z)
    if(item){
        item.featuresConfig = imageItems.value
    }else {
        const blob = base64ToBlob(base64);
        const file = new File([blob], 'image.png', { type: blob.type });
        await uploadImage(file,z).then(res => {
            if(!res.data){
                return;
            }
            item = {
                videoUrl: props.editImageItem.data.url,
                imageUrl: res.data,
                videoFrames: z,
                featuresConfig: imageItems.value
            }
            videoImages.value.push(item)
            // 对 videoImages 按照 frame 排序
            videoImages.value.sort((a, b) => a.frame - b.frame);
        }).catch(e => {

        })
    }
    emits('onSave', item)
}

const base64ToBlob = (base64Data) => {
    const parts = base64Data.split(';base64,');
    const contentType = parts[0].split(':')[1];
    const raw = window.atob(parts[1]);
    const rawLength = raw.length;
    const uInt8Array = new Uint8Array(rawLength);

    for (let i = 0; i < rawLength; ++i) {
        uInt8Array[i] = raw.charCodeAt(i);
    }

    return new Blob([uInt8Array], { type: contentType });
};

const uploadImage = (file,z) => {
    return FileUploadService.uploadStrategy({
        file: file,
        path: 'image/'+props.editImageItem.data.classificationId,
        class: 'imageProxy',
        languageClassificationId: props.editImageItem.data.languageClassificationId,
        classificationId: props.editImageItem.data.classificationId,
        videoFrames: z,
        videoUrl: props.editImageItem.data.url
    })
}

const onClose = () => {
    emits('onClose')
}

const onVideoProgressChange = (value) => {
    if(!video) return
    frameMap = {}
    video.currentTime = value;
}

const onVideoState = () => {
    videoProgress.value.start = !videoProgress.value.start;
    if(videoProgress.value.start){
        video.play()
    }else{
        video.pause()
    }
}

const onLeft = () => {
    // 获取图片列表容器
    const sliderList = document.getElementById('sliderList');
    if(sliderList.children.length < 1){
        return
    }
    let width = sliderList.children[0].clientWidth + 5
    // 每张图片的宽度
    const itemWidth = sliderList.offsetWidth / width;
    // 当前显示的图片索引
    let currentIndex = 0;
    if (currentIndex > 0) {
        currentIndex--;
        const targetTranslate = -currentIndex * itemWidth;
        sliderList.style.transform = `translateX(${targetTranslate}px)`;
    }
}

const onRight = () => {
    // 获取图片列表容器
    const sliderList = document.getElementById('sliderList');
    if(sliderList.children.length < 1){
        return
    }
    let width = sliderList.children[0].clientWidth + 5
    // 每张图片的宽度
    const itemWidth = sliderList.offsetWidth / width;

    // 图片总数
    const totalItems = sliderList.children.length;
    // 每次显示的图片数量
    const visibleItems = 10;
    if (currentIndex < totalItems - visibleItems) {
        currentIndex++;
        const targetTranslate = -currentIndex * itemWidth;
        sliderList.style.transform = `translateX(${targetTranslate}px)`;
    }
}

const onDelImage = (item,index) => {
    ImageClassificationService.delImageItem([item.imageUrl]).then(res => {
        message.success("删除成功")
        videoImages.value.splice(index, 1)
        if(item?.videoFrames !== video?.currrentTime){
            return
        }
        imageItems.value = []
        clearAllRect()
    })
}

onMounted(() => {
    props.editImageItem.title = '视频物体标注'
    props.editImageItem.width = '60%'
    show()
})

</script>

<template>
    <el-row :class="{'dialog-modal':true,'dialog-menu-fold': menuFoldState}">
        <el-button style="position: absolute;top: 0;right: 0" type="primary"
                   :icon="CloseBold" @click="onClose"/>
        <el-row class="main">
            <el-row id="canvas-row" style="width: 65%;height: 100%" class="left">
                <canvas id="canvas">
                    <video id="video"
                           crossorigin="anonymous"/>
                </canvas>
            </el-row>
            <el-row class="right" style="width: 35%;height: 100%;">
                <el-row class="image-list">
                    <el-card :key="idx" :body-style="{ padding: '10px' }" v-for="(item,idx) in imageItems"
                             style="height: 80px;width: 100%;">
                        <el-form :key="idx" :model="editImageItem" style="width: 100%;height: 100%" label-width="70"
                                 label-position="left">
                            <el-row style="width: 100%;">
                                <el-form-item label="特征信息" style="width: 100%">
                                    <el-select
                                        v-model="item.typeID"
                                        clearable
                                        @change="e => onChangeFeaturesName(e, item.id)"
                                    >
                                        <el-option
                                            v-for="item in featuresList"
                                            :key="item.id"
                                            :label="item.featuresName"
                                            :value="item.id"
                                        />
                                    </el-select>
                                    <el-input style="display: none;" v-model="item.featuresName"/>
                                    <el-row style="width: 100%;font-size: 12px">
                                        <el-col :span="10">
                                            原点(x,y)=({{ item.x }},{{ item.y }})
                                        </el-col>
                                        <el-col :span="12">
                                            框选(宽,高)=({{ item.width + ',' + item.height }})
                                        </el-col>
                                        <el-col :span="2">
                                            <el-row style="width: 100%;padding-top: 5px" justify="end">
                                                <el-button type="danger" size="small" :icon="Delete" circle
                                                           @click="onDelRect(item,idx)"/>
                                            </el-row>
                                        </el-col>
                                    </el-row>
                                </el-form-item>
                            </el-row>
                        </el-form>
                    </el-card>
                </el-row>
                <!-- 图片预览组件 -->
                <!-- 滑动容器 -->
                <div class="slider-container">
                    <!-- 图片列表 -->
                    <div class="slider-list" id="sliderList">
                        <div class="slider-list-item" v-for="(item,index) in videoImages">
                            <el-icon @click="onDelImage(item,index)" class="slider-list-del"><CircleCloseFilled /></el-icon>
                            <el-image style="height: 50px;"
                                      :src="`${url}${item.imageUrl}`"
                                      :zoom-rate="1.2"
                                      :max-scale="7"
                                      :min-scale="0.2"
                                      fit="cover"
                            />
                        </div>
                    </div>
                    <!-- 左按钮 -->
                    <button class="slider-button left" @clik="onLeft">
                        <el-icon><ArrowLeftBold /></el-icon>
                    </button>
                    <!-- 右按钮 -->
                    <button class="slider-button right" @click="onRight">
                        <el-icon><ArrowRightBold /></el-icon>
                    </button>
                </div>
                <!-- 视频控制组件 -->
                <el-row class="progress" >
                    <el-col :span="3">
                        <el-row style="width: 100%;height: 30px">
                            <el-icon class="progress-btn" @click="onVideoState" v-if="videoProgress.start"><VideoPause /></el-icon>
                            <el-icon class="progress-btn" @click="onVideoState" v-if="!videoProgress.start"><VideoPlay /></el-icon>
                        </el-row>
                    </el-col>
                    <el-col :span="21">
                        <el-row style="width: 100%;height: 30px">
                            <el-slider style="width: 95%;margin-top: -1px" @input="onVideoProgressChange" v-model="videoProgress.progress" :max="videoProgress.progressMax" />
                        </el-row>
                    </el-col>
                </el-row>
                <el-button type="primary" class="save" @click="onSave">
                    保存标注信息
                </el-button>
            </el-row>
        </el-row>
    </el-row>
</template>

<style scoped lang="scss">
.dialog-menu-fold {
    left: 63px !important;
    width: calc(100% - 63px) !important;
    transition-property: left, width;
    transition-duration: .4s;
    transition-timing-function: ease;
}

.dialog-modal {
    width: calc(100% - 200px);
    height: calc(100vh - 59px);
    top: 59px;
    left: 200px;
    position: absolute;
    background-color: rgba(0, 0, 0, 0.5);
    z-index: 10;
}

:deep(.dialog-row-content) {
    height: 100% !important;
    overflow-y: hidden;
}

.main {
    height: 85%;
    width: 85%;
    margin: auto;
    background-color: #0a0a0a;
    float: left;
}

.save {
    width: 100%;
    height: 40px;
}

:deep(.el-button) {
    border-radius: 0 !important;
}

.image-list {
    width: 100%;
    height: calc(100% - 140px);
    padding: 5px;
    overflow-y: auto;
    flex-direction: row;
    gap: 5px;
    align-content: start;
    background-color: var(--el-bg-color);
}

.progress{
    height: 30px;
    width: 100%;
    background-color: var(--el-bg-color);
    .progress-btn{
        margin: auto 5px;
        font-size: 1.5em;
        color: rgb(121.3, 187.1, 255);
        cursor: pointer;
        font-weight: 800;
    }
}


/* 滑动容器样式 */
.slider-container {
    position: relative;
    width: 90%;
    margin: 0 auto;
    overflow: hidden;
    white-space: nowrap; /* 防止换行 */
    /* 图片列表样式 */
    .slider-list {
        height: 50px;
        padding: 10px 20px;
        display: flex;
        gap: 5px;
        width: max-content; /* 根据内容自动扩展宽度 */
        transition: transform 0.3s ease;

        .slider-list-item{
            height: 50px;
            position: relative;

            .slider-list-del{
                position: absolute;
                top:-1px;
                right:-1px;
                font-size: 1em;
                z-index: 999;
                cursor: pointer;
            }

        }
    }

    /* 按钮样式 */
    .slider-button {
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        background-color: rgba(0, 0, 0, 0.5);
        color: white;
        border: none;
        padding: 5px;
        cursor: pointer;
        z-index: 99;
    }

    /* 左按钮样式 */
    .slider-button.left {
        left: 0;
    }

    /* 右按钮样式 */
    .slider-button.right {
        right: 0;
    }

}

</style>